package com.lh.jianzhioffer.专项练习.链表;

/**
 * @author: linghao
 * @since: 2023/3/6
 *
 * 给定一个链表，返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环，则返回 null。
 *
 * 为了表示给定链表中的环，我们使用整数 pos 来表示链表尾连接到链表中的位置（索引从 0 开始）。 如果 pos 是 -1，则在该链表中没有环。注意，pos 仅仅是用于标识环的情况，并不会作为参数传递到函数中。
 *
 * 说明：不允许修改给定的链表
 *
 * hash发或者快慢指针
 *
 */
public class 链表中环的入口节点022 {

    public ListNode detectCycle(ListNode head) {

        if (head == null) {
            return null;
        }

        for(ListNode fast=head,slow=head;fast!=null && slow!=null;){
            if(fast.next == null || slow == null)return null;

            fast = fast.next.next;
            slow = slow.next;

            if(fast == slow){ //第一次相遇可能不是在入口节点
                ListNode tmp=head;
                while (tmp != slow){  //从头节点开始和慢指针再相遇一次即是入口
                    tmp = tmp.next;
                    slow = slow.next;
                }
                return tmp;
            }

        }
        return null;
    }


    class ListNode {
      int val;
      ListNode next;
      ListNode(int x) {
          val = x;
          next = null;
      }
  }
}
